<!doctype html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>pakku :: 选项</title>
    <link rel="stylesheet" href="/assets/icomoon/icon.css">
    <style>
        body {
            background-color: #f7f7f7;
            font-family: '微软雅黑', 'Microsoft Yahei', '宋体', sans-serif;
            min-width: 800px;
            margin: 0;
            font-size: 100%;
        }
        .hidden {
            display: none;
        }
        .font-bili-danmu {
            font-family: SimHei, "Microsoft JhengHei", Arial, Helvetica, sans-serif;
        }
        a {
            color: #000077;
            text-decoration: none;
            border-bottom: 1px solid #000077;
        }
        hr {
            border: initial;
            border-top: 1px solid #aaa;
            margin: 2em 0 2em 0;
        }
        #title {
            vertical-align: middle;
            font-family: Consolas, Courier, '微软雅黑', 'Microsoft Yahei', '宋体', monospace;
        }
        #logo-text {
            font-size: 50px;
        }
        #title img {
            vertical-align: middle;
        }
        label {
            font-weight: bold;
        }
        code {
            color: #007700;
            border-bottom: 1px dashed #007700;
        }
        code, .code {
            font-family: Consolas, Courier, '微软雅黑', 'Microsoft Yahei', monospace;
        }
        p {
            margin-top: 1em;
            margin-bottom: 1em;
        }
        p.warning {
            margin-top: -.7em;
            margin-left: 3em;
            color: rgba(0,0,0,.8);
            font-size: .85em;
        }
        p.warning a {
            color: inherit;
            border-color: inherit;
        }
        p.warning b {
            color: #770000;
            border-bottom: 1px solid black;
        }
        table {
            border-spacing: 0;
            width: 100%;
        }
        tr {
            transition: box-shadow 200ms, background-color 200ms;
        }
        tr:hover:not(#title) {
            background-color: #fcfcfc;
            box-shadow: 0 2px 25px rgba(0,0,0,.3);
        }
        td {
            border-top: 1px solid #aaa;
            padding: 1em;
        }
        td:nth-child(1), td:nth-child(4) {
            width: calc(50% - 450px);
        }
        td:nth-child(2) {
            min-width: 150px;
            width: 150px;
            font-size: 1.5em;
            padding-right: 1em;
            padding-top: 1em;
            text-align: right;
            vertical-align: top;
        }
        td:nth-child(3) {
            min-width: 750px;
            width: 750px;
        }
        a[data-help-text] {
            cursor: pointer;
        }
        .list {
            margin-bottom: 1em;
        }
        .list:empty::after {
            content: "（列表为空）";
            color: rgba(0,0,0,.8);
        }
        .list code[contenteditable]:not(:focus) {
            cursor: pointer;
        }
        .list code {
            word-break: break-all;
        }
        .list li {
            margin-bottom: .2em;
        }
        .list .btn {
            margin-left: 1em;
        }
        #saved-alert {
            position: fixed;
            top: 35px; right: -5px;
            width: 100px;
            height: 30px;
            line-height: 30px;
            font-size: 20px;
            text-align: left;
            padding-left: 10px;
            border-radius: 5px;
            background-color: black;
            color: white;
        }
        #saved-alert.saved-hidden {
            right: -110px;
            transition: right .2s ease 1s;
        }
        td p {
            position: relative;
        }
        .img-panel {
            position: absolute;
            bottom: 2em;
            left: -50px;
            width: 850px;
            display: none;
            pointer-events: none;
        }
        p:hover .img-panel {
            display: inline-block;
        }
        .darkblue, .icon-image {
            color: darkblue;
        }
        .img-active {
            border: 2px solid #00aa00;
        }
        .img-inactive {
            border: 2px solid #ff4444;
            filter: brightness(.8) contrast(.5);
            -webkit-filter: brightness(.8) contrast(.5);
        }
        #highlighter {
            position: relative;
            top: -0.25em;
            left: -5em;
            width: 5em;
            margin-right: -5em;
            font-size: 2em;
            float: left;
            animation: highlight-blink 1s 2;
            text-align: right;
            color: #3b6;
        }
        #highlighter::after {
            content: '→';
        }
        @keyframes highlight-blink {
            from {background-color: #3fa; color: #000;}
            50% {background-color: #3d7; color: #000;}
            to {background-color: #3fa; color: #000;}
        }
        #note-banner-container {
            position: sticky;
            z-index: 1;
            top: 0;
            left: 0;
            width: 100%;
            max-width: calc(900px + 4rem);
            margin: auto;
            font-size: 20px;
            text-align: center;
        }
        #note-banner-container a {
            display: block;
            background-color: yellow;
            border: 2px solid black;
            padding: 4px;
            margin: 4px;
            white-space: pre-wrap;
            cursor: not-allowed;
        }
        #note-banner-container a[href] {
            cursor: pointer;
        }
        #note-banner-container a[href]:hover {
            background-color: lightyellow;
        }
        #version-checker {
            font-size: .8em;
            opacity: .6;
        }
        #donate-img {
            display: none;
            position: fixed;
            z-index: 999;
        }
        .donate-show #donate-img {
            display: initial;
            margin: auto;
            top: 0; bottom: 0; left: 0; right: 0;
            border: 3px solid #666;
            pointer-events: none;
        }
        label[for=show-advanced], .advanced:not(.warning) {
            background-color: rgba(0, 0, 255, .09);
        }
        body:not(.i-am-advanced) .advanced:not(.js-show-this) {
            display: none;
        }
    </style>
</head>
<body>
    <div id="note-banner-container"></div>
    <table class="full-width">
        <tbody>
            <tr id="title">
                <td></td>
                <td>
                    <img src="/assets/logo.png" height="128" width="128">
                </td>
                <td>
                    <p><span id="logo-text">pakku <small>:: 哔哩哔哩弹幕过滤器</small></span></p>
                    <p>
                        <input id="show-advanced" type="checkbox">
                        <label for="show-advanced">我是高级用户，给我显示所有设置</label>
                        |
                        <span id="version"></span> by @xmcp
                        <a class="donate"><span class="icon-coin"></span>打赏</a>
                        <a href="troubleshooting.html" target="_blank"><span class="icon-github"></span>报告问题</a>
                        <span id="version-checker"></span>
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td>弹幕合并</td>
                <td>
                    <p>
                        <label for="threshold">时间阈值：</label>
                        合并时间差在
                        <input id="threshold" type="number" min="-1" step="1" max="180">
                        秒之内的重复弹幕
                    </p>
                    <p class="warning">
                        * 超长（大概 60 秒以上？）的阈值可能会导致程序运行缓慢
                    </p>
                    <p class="advanced">
                        <label for="max-dist">编辑距离合并阈值</label>
                        <select id="max-dist">
                            <option value="0">禁用</option>
                            <option value="3">轻微 (≤3)</option>
                            <option value="5">中等 (≤5)</option>
                            <option value="8">强力 (≤8)</option>
                            <option class="other"></option>
                        </select>
                        <label for="max-dist">：</label>
                        <span>
                            根据编辑距离判断不完全一致但内容相近（例如有错别字）的弹幕
                        </span>
                    </p>
                    <p class="advanced warning">
                        * 能有效击杀 "<code>你指尖跃动的电光</code>" 和 "<code>你<b>之间</b>跃动的电光</code>" 等，
                        感谢 <a href="https://github.com/dramforever" target="_blank">@dramforever</a>
                    </p>
                    <p class="advanced">
                        <label for="max-cosine">词频向量合并阈值</label>
                        <select id="max-cosine">
                            <option value="1000">禁用</option>
                            <option value="60">轻微 (60%)</option>
                            <option value="45">中等 (45%)</option>
                            <option value="30">强力 (30%)</option>
                            <option class="other"></option>
                        </select>
                        <label for="max-cosine">：</label>
                        <span>
                            根据 2-Gram 频率向量的夹角判断不完全一致但内容类似的弹幕
                        </span>
                    </p>
                    <p class="advanced warning">
                        * 能有效击杀 "<code>yeah!~</code>" 和 "<code>yeah!~yeah!~yeah!~yeah!~</code>" 等，
                        感谢 <a href="https://github.com/fanthos" target="_blank">@fanthos</a>
                    </p>
                    <p class="advanced">
                        <input id="trim-pinyin" type="checkbox">
                        <label for="trim-pinyin">识别谐音弹幕：</label>
                        <span>将常用汉字转换为拼音再进行比较</span>
                    </p>
                    <p class="advanced warning">
                        * 能有效击杀 "<code>布拉迪巴特福来</code>" 和 "<code>布拉迪·八德福莱</code>" 等，
                        感谢 <a href="https://github.com/sxei/pinyinjs" target="_blank">@sxei</a>
                    </p>
                    <p class="advanced">
                        <b>比较文本时：</b>
                        <input id="trim-ending" type="checkbox">
                        <label for="trim-ending">忽略末尾标点</label>
                        /
                        <input id="trim-space" type="checkbox">
                        <label for="trim-space">忽略多余空格</label>
                        /
                        <input id="trim-width" type="checkbox">
                        <label for="trim-width">忽略全半角差异</label>
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td>例外设置</td>
                <td>
                    <div class="advanced">
                        <p><b>强制合并</b>：（符合这些规则的弹幕，在比较是否相同时会先进行替换）</p>
                        <form id="newforcelist-form">
                            <p>
                                <input id="newforcelist-pattern" class="code" placeholder="正则表达式" required>
                                →
                                <input id="newforcelist-name" placeholder="替换为" required>
                                <button type="submit">添加</button>
                                &nbsp; <small><a href="https://s.xmcp.ltd/pakkujs/regex-help.png" target="_blank">一张图看懂正则表达式</a></small>
                            </p>
                        </form>
                        <div class="list" id="forcelist"></div>
                        <hr>
                        <p><b>强制忽略</b>：（符合这些规则的弹幕，即使内容相同也不会被合并）</p>
                        <form id="newwhitelist-form">
                            <p>
                                <input id="newwhitelist-pattern" class="code" placeholder="正则表达式" required>
                                <button type="submit">添加</button>
                                &nbsp; <small><a href="https://s.xmcp.ltd/pakkujs/regex-help.png" target="_blank">一张图看懂正则表达式</a></small>
                            </p>
                        </form>
                        <div class="list" id="whitelist"></div>
                        <hr>
                    </div>
                    <p>
                        <input id="cross-mode" type="checkbox">
                        <label for="cross-mode">合并不同类型的弹幕：</label>
                        取消勾选后，底部弹幕不会跟滚动弹幕合并到一起
                    </p>
                    <p id="batch-ignore-panel">
                        <b>放过特定类型的弹幕：</b>
                        <input id="ignore-pool1" type="checkbox">
                        <label for="ignore-pool1">字幕弹幕</label>
                        /
                        <input id="ignore-type7" type="checkbox">
                        <label for="ignore-type7">高级弹幕</label>
                        /
                        <input id="ignore-type4" type="checkbox">
                        <label for="ignore-type4">底部弹幕</label>
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td>显示设置</td>
                <td>
                    <p>
                        <label for="danmu-mark">弹幕数量标记 <span class="icon-image"></span> </label>
                        <select id="danmu-mark">
                            <option value="suffix">显示在结尾</option>
                            <option value="prefix">显示在开头</option>
                            <option value="off">不显示</option>
                        </select>
                        <span id="mark-threshold-panel">
                            ，仅当数字大于
                            <input id="mark-threshold" type="number" min="1" step="1" max="9999">
                            时显示
                        </span>
                        <span class="img-panel">
                            <img src="img/danmu-suffix.png" height="100" width="200" data-name="DANMU_MARK" data-value="suffix">
                            <img src="img/danmu-prefix.png" height="100" width="200" data-name="DANMU_MARK" data-value="prefix">
                            <img src="img/danmu-off.png" height="100" width="200" data-name="DANMU_MARK" data-value="off">
                        </span>
                    </p>
                    <p id="danmu-subscript-panel" class="advanced">
                        <input id="danmu-subscript" type="checkbox">
                        <label for="danmu-subscript">数量标记显示成下标：</label>
                        <span><code class="font-bili-danmu">₍₂₎就像这样</code>，<code class="font-bili-danmu">[x2]而不是这样</code></span>
                    </p>
                    <p>
                        <input id="enlarge" type="checkbox">
                        <label for="enlarge">弹幕合并后增大字号 <span class="icon-image"></span>：</label>
                        <span>超过 5 条弹幕被合并后字号将相应变大，避免内容被忽略</span>
                        <span class="img-panel">
                            <img src="img/enlarge-bef.png" height="200" width="400" data-name="ENLARGE" data-value="off">
                            <img src="img/enlarge-aft.png" height="200" width="400" data-name="ENLARGE" data-value="on">
                        </span>
                    </p>
                    <p>
                        <label for="shrink-threshold">自动减小字号 <span class="icon-image"></span></label>
                        <select id="shrink-threshold">
                            <option value="0">禁用</option>
                            <option value="120">轻微 (>120)</option>
                            <option value="75">中等 (>75)</option>
                            <option value="50">强力 (>50)</option>
                            <option class="other"></option>
                        </select>
                        <label for="max-dist">：</label>
                        <span>瞬时弹幕密度大于阈值时，按比例减小字号以避免遮挡画面</span>
                        <span class="img-panel">
                            <img src="img/shrink-bef.png" height="200" width="400" data-name="SHRINK_THRESHOLD" data-value="0">
                            <img src="img/shrink-aft.png" height="200" width="400" data-name="SHRINK_THRESHOLD" data-value="!0">
                        </span>
                    </p>
                    <p>
                        <label for="drop-threshold">自动弹幕优选</label>
                        <select id="drop-threshold">
                            <option value="0">禁用</option>
                            <option value="120">轻微 (>120)</option>
                            <option value="75">中等 (>75)</option>
                            <option value="50">强力 (>50)</option>
                            <option class="other"></option>
                        </select>
                        <label for="drop-threshold">：</label>
                        <span>瞬时弹幕密度大于阈值时，按比例删除低权重弹幕，优先删除未合并弹幕</span>
                    </p>
                    <p class="advanced">
                        <label for="representative-percent">合并后的弹幕显示于 </label>
                        <select id="representative-percent">
                            <option value="0">0%</option>
                            <option value="20">20%</option>
                            <option value="50">50%</option>
                            <option class="other"></option>
                        </select>
                        <label for="representative-percent"> 百分位弹幕的时间点</label>
                    </p>
                    <p class="advanced">
                        <input id="mode-elevation" type="checkbox">
                        <label for="mode-elevation">合并后尽量显示为固定弹幕：</label>
                        <span>滚动弹幕和顶部 / 底部弹幕合并后显示在顶部 / 底部</span>
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
            <td></td>
            <td>播放器增强</td>
            <td>
                    <p>
                        <input id="tooltip" type="checkbox">
                        <label for="tooltip">弹幕信息显示框 <span class="icon-image"></span>：</label>
                        <span>在弹幕列表中点击弹幕来显示详细信息</span>
                        <span class="img-panel">
                            <img src="img/tooltip.png" height="300" width="600" data-name="TOOLTIP" data-value="on">
                        </span>
                    </p>
                    <p class="warning">
                        * 还可以查询弹幕发送者（仅支持部分用户 <a data-help-text="仅支持查询 2022 年之前注册（UID 不超过 10 位数字）的用户。\n\n弹幕发送者信息经过不可逆的 CRC32 哈希处理，因此对一条弹幕会查询出多个可能的发送者。">[?]</a>），
                        感谢 <a href="https://github.com/dramforever" target="_blank">@dramforever</a>
                    </p>
                    <p id="tooltip-keybinding-panel">
                        <input id="tooltip-keybinding" type="checkbox">
                        <label for="tooltip-keybinding">点击展开弹幕信息：</label>
                        <span>按住 Ctrl / Command 键点击屏幕上的弹幕显示详细信息</span>
                    </p>
                    <p id="auto-panel">
                        <b>播放器自动化：</b>弹幕载入后，自动
                        <input id="auto-danmu-list" type="checkbox">
                        <label for="auto-danmu-list">显示弹幕列表</label>
                        /
                        <input id="auto-disable-danmu" type="checkbox">
                        <label for="auto-disable-danmu">关闭弹幕</label>
                    </p>
                    <p id="fluctlight-panel">
                        <input id="fluctlight" type="checkbox">
                        <label for="fluctlight">弹幕密度分析图 <span class="icon-image"></span>：</label>
                        <span>鼠标移过进度条时可视化弹幕密度</span>
                        <span class="img-panel">
                            <img src="img/fluctlight.png" height="300" width="600" data-name="FLUCTLIGHT" data-value="on">
                        </span>
                    </p>
                <p class="warning">
                    * 蓝色、黄色、红色分别表示实际显示的、被 pakku 合并的、被删除的 <a data-help-text="被删除的弹幕包括命中播放器屏蔽词，以及被 pakku 的用户脚本和 “自动弹幕优选” 功能删除的弹幕">[?]</a> 弹幕密度
                </p>

            </td>
            <td></td>
            </tr>
            <tr>
                <td></td>
                <td>实验室</td>
                <td>
                    <p>
                        <input id="break-update" type="checkbox">
                        <label for="break-update">阻止弹幕动态更新：</label>
                        <span>如果你发现很多刷屏弹幕没有被过滤，请选中本选项</span>
                    </p>
                    <p class="warning">
                        * 选中后，观看视频时将<b>不会动态更新弹幕</b>，也不会显示在线人数
                    </p>
                    <p>
                        <input id="takeover-aijudge" type="checkbox">
                        <label for="takeover-aijudge">阻止弹幕云屏蔽：</label>
                        <span>禁用B站播放器的弹幕智能云屏蔽功能</span>
                    </p>
                    <p class="warning">
                        * pakku 的 <a href="#drop-threshold">自动弹幕优选</a> 是效果更好的替代方案，启用本选项将阻止播放器二次过滤弹幕
                    </p>
                    <p>
                        <label for="scroll-threshold">关怀小屏幕用户：</label>
                        将总长度超过
                        <input id="scroll-threshold" type="number" min="1" step="1" max="9999">
                        像素的底部、顶部弹幕转换为滚动弹幕
                    </p>
                    <p class="warning">
                        * 设为 0 来禁用此功能
                    </p>
                    <p class="advanced">
                        <span style="font-weight: bold" id="userscripts">全局用户脚本：</span>
                        <a href="userscript_editor.html" target="_blank">前去设置</a>
                    </p>
                    <p class="advanced warning">
                        * 用于深度自定义 pakku 功能，可以通过 JavaScript 回调函数来修改弹幕内容
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td>其他设置</td>
                <td>
                    <p class="advanced">
                        <label for="combine-threads">并行处理：</label>
                        使用
                        <input id="combine-threads" type="number" min="0" step="1" max="6">
                        个后台线程
                    </p>
                    <p class="advanced warning">
                        * 对于长视频（如电影），适当增加线程数量以加快处理速度；对于短视频，适当减少线程数量以缩短初始化时间；设置为 0 来完全禁用后台线程（处理弹幕时将阻塞页面）
                    </p>
                    <p class="advanced">
                        <label for="popup-badge">扩展程序角标 </label>
                        <select id="popup-badge">
                            <option value="percent">显示被合并弹幕百分比</option>
                            <option value="count">显示被合并弹幕数量</option>
                            <option value="dispval">显示最大弹幕密度</option>
                            <option value="off">不显示角标</option>
                        </select>
                        <label for="popup-badge">：</label>
                        <span>在右上角的 pakku 图标上显示当前视频的统计信息</span>
                    </p>
                    <p class="advanced warning">
                        * 在视频页面点击 pakku 图标可以查看更详细的统计信息
                    </p>
                    <p class="advanced">
                        <input id="read-player-blacklist" type="checkbox">
                        <label for="read-player-blacklist">读取播放器屏蔽词：</label>
                        <span>在合并弹幕前按播放器的屏蔽词过滤弹幕</span>
                    </p>
                    <p class="advanced warning">
                        * 使数量标记和弹幕密度计算更准确，并避免数量标记影响正则匹配，但将无法在弹幕列表中看到被屏蔽的弹幕；可以在播放器页面的 <code>localStorage</code> 中添加额外的屏蔽词 <a data-help-text="当屏蔽词数量过多，超出播放器限制或者造成了性能问题时，可以将屏蔽词存储在播放器域名的 localStorage 的 pakku_extra_blacklist 项中，pakku 将额外导入这些屏蔽词。\n\n屏蔽词格式与播放器导出的 JSON 格式相同，例如：\n\nlocalStorage['pakku_extra_blacklist'] = JSON.stringify([{type: 1, filter: '^.{1,6}[天时点分钟秒]前', opened: true, id: 0}]);">[?]</a>
                    </p>
                    <p>
                        （一些面向高级用户的 <a href="#show-advanced">复杂的设置</a>
                        <span class="advanced">现在并没有</span>
                        被隐藏了）
                    </p>
                    <p>
                        <button type="button" id="reset">重置所有设置</button>
                        <button type="button" id="backup-restore">导入 / 导出设置</button>
                    </p>
                </td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td>关于</td>
                <td>
                    <p>
                        <strong>xmcp/pakku.js</strong>
                        使用 <a href="https://github.com/xmcp/pakku.js/blob/master/LICENSE.txt" target="_blank">GPL 3.0 协议</a>
                        在 <a href="https://github.com/xmcp/pakku.js/" target="_blank"><span class="icon-github"></span> GitHub</a> 开放源代码。
                    </p>
                    <p>
                        <strong>我，开发者，打钱 <span class="icon-coin darkblue"></span></strong>
                        <a class="donate">→投喂开发者← (｀・ω・´)</a>
                    </p>
                    <hr>
                    <p>
                        <strong>觉得 pakku 很赞？</strong>
                        请把 pakku ( <code>https://s.xmcp.ltd/pakku</code> ) 安利给更多的小伙伴们 _(:3」∠)_
                    </p>
                    <p>
                        <strong>给个五星好评吧！</strong>
                        前往
                        <a id="ask-review-link" href="https://chromewebstore.google.com/detail/pakku%EF%BC%9A%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E5%BC%B9%E5%B9%95%E8%BF%87%E6%BB%A4%E5%99%A8/jklfcpboamajpiikgkbjcnnnnooefbhh/reviews" target="_blank">
                            Chrome Web Store（需要魔法上网）
                        </a>
                        打分。
                    </p>
                    <p>
                        <strong>想要更多功能？</strong>
                        <span class="advanced">
                            <a href="userscript_editor.html">通过用户脚本来自定义</a>
                            或者
                        </span>
                        <a href="https://github.com/xmcp/pakku.js/issues" target="_blank">在 GitHub 上提出</a>
                        。
                    </p>
                    <p>
                        全部运算都在本地进行，我们不会收集你的B站账号信息和观看历史。
                        <a href="https://s.xmcp.ltd/pakkujs/privacy_policy.html" target="_blank">Privacy Policy</a>
                    </p>
                </td>
                <td></td>
            </tr>
        </tbody>
    </table>

    <br><br>

    <div id="saved-alert" class="saved-hidden">✓ 已保存</div>
    <img id="donate-img" src="https://s.xmcp.ltd/pakkujs/donate.png">

    <script type="module" src="/generated/options.js"></script>
</body>
</html>
